#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>


int main()
{
    signal(SIGCHLD, SIG_IGN);
    pid_t id = fork();
    if (id == 0)
    {
        int cnt = 5;
        while (cnt)
        {
            std::cout << "child running" << std::endl;
            cnt--;
            sleep(1);
        }
        exit(1);
    }
    
    while (true)
    {
        std::cout << "father running" << std::endl;
        sleep(1); 
    }
    

    return 0;
}


// void notice(int sig)
// {
//     std::cout << "get a signal: " << sig << "pid: " << getpid() << std::endl;
//     //这个循环只要开始执行，就会分两步走：
//     //  第一步： 把所有能够等得到的已结束子进程回收，
//     //  第二步： 回收完毕之后，如果出现一下情况中的一种，则退出循环
//     //          case1: 没有子进程需要被等待了
//     //          case2: 等待一个进程，但是没有等到
//     while (true)
//     {
//         // 将等待方式设为WNOHANG是因为防止只有一部分子进程退出，而另一部分进程不退
//         // WNOHANG作为非阻塞等待，让父进程等不到也不会阻塞
//         pid_t rid = waitpid(-1, nullptr, WNOHANG);
//         if (rid > 0)
//         {
//             std::cout << "wait child success, rid: " << rid << std::endl;
//         }
//         else if (rid < 0) // rid小于0表示已经没有子进程需要被等待了
//         {
//             std::cout << "wait child success done" << std::endl;
//             break;
//         }
//         else // rid 等于0表示等待一个进程，但是没有等到
//         {
//             std::cout << "wait child success done" << std::endl;
//             break;
//         }
//     }
// }

// void doOtherThing()
// {
//     std::cout << "doOtherThing------" << std::endl;
//     sleep(1);
// }

// int main()
// {
//     //  下面这句让父进程在收到子进程发送的信号时，会执行 notice这个函数
//     //  而Linux中信号是以位图的形式，只要有一个子进程结束以后，率先发出SIGCHLD信号
//     //  就会进入 notice 的循环，而且在notice的执行过程中会一直执行到 while 的代码块中执行到break语句才会考虑 可能的信号
//     signal(SIGCHLD, notice);

//     for (size_t i = 0; i < 10; i++)
//     {
//         pid_t id = fork();
//         if (id == 0)
//         {
//             // child
//             std::cout << "I am a child process, pid: " << getpid() << std::endl;
//             sleep(3);
//             exit(1);
//         }
//     }

//     // father
//     while (true)
//     {
//         doOtherThing();
//     }

//     return 0;
// }

// volatile int gflag = 0;
// // int gflag = 0;

// void changedata(int sig)
// {
//     std::cout << "get a sig: " << sig << ", change gflag 0->1" << std::endl;
//     gflag = 1;
// }

// int main()
// {
//     signal(2, changedata);
//     while (!gflag);
//     std::cout << "process quit normal" << std::endl;

// }

// void Print(sigset_t pending)
// {
//     for (int sig = 31; sig > 0; sig--)
//     {
//         if (sigismember(&pending, sig))
//         {
//             std::cout << 1;
//         }
//         else
//         {
//             std::cout << 0;
//         }
//     }
//     std::cout << std::endl;
// }

// void handler(int sig)
// {
//     std::cout << "get a sig:  " << sig << std::endl;
//     while (true)
//     {
//         sigset_t pending;
//         sigpending(&pending);
//         Print(pending);
//         sleep(3);
//         break;
//     }

//     // exit(1);
// }

// int main()
// {
//     struct sigaction act, oact;
//     act.sa_handler = handler;
//     sigemptyset(&act.sa_mask);
//     sigaddset(&act.sa_mask, 3);
//     act.sa_flags = 0;

//     sigaction(2, &act, &oact);

//     while (true)
//     {
//         std::cout << "I am a process, pid: " << getpid() << std::endl;
//         sleep(1);
//     }

//     return 0;
// }
//
